#ifndef _ACTION_H_
#define _ACTION_H_

#include "daemon.h"
#include "disk.h"

#include <QFile>

#include <iostream> //debug
using std::cout;
using std::endl;

namespace Tubox {

class Action {
public:
	virtual bool doIt(Daemon* daemon) = 0;
protected:
	Action() { }
};

/**
 * Empty Action :)
 */

class NoAction : public Action {
public:
	NoAction() { }
	bool doIt(Daemon*) { return true; }
};

/**
 * File Action
 */

class FileAction : public Action {
public:
	virtual bool doIt(Daemon* daemon) = 0;
protected:
	FileAction(const File& file) : file(file) { }

	File file;
};

class DownloadFileAction : public FileAction {
public:
	DownloadFileAction(const File& file) : FileAction(file) { }

	bool doIt(Daemon* daemon){
		return daemon->askDownload(file.getPath(), file.getName());
	}
};

class DeleteFileAction : public FileAction {
public:
	DeleteFileAction(const File& file) : FileAction(file) { }

	bool doIt(Daemon* daemon) {
		return daemon->askDelete(file.getPath(), file.getName());
	}
};

class DeleteLocalFileAction : public FileAction {
public:
	DeleteLocalFileAction(const File& file) : FileAction(file) { }

	bool doIt(Daemon* daemon) {
		try {
			daemon->getDisk()->remove(file);
			return true;
		}
		catch(FileSystemError& e){
			return false;
		}
	}
};

class UpdateFileAction : public FileAction {
public:
	UpdateFileAction(const File& file) : FileAction(file) { }

	bool doIt(Daemon* daemon) {
		return daemon->askUpload(file.getPath(), file.getName(), file.getData(), file.getVersion());
	}
};


/**
 * Folder Action
 */


class FolderAction : public Action {
public:
	virtual bool doIt(Daemon* daemon) = 0;
protected:
	FolderAction(const Folder& folder) : folder(folder) { }

	Folder folder;
};


class CreateFolderAction : public FolderAction {
public:
	CreateFolderAction(const Folder& folder) : FolderAction(folder) { }

	bool doIt(Daemon* daemon) {
		return daemon->askMkdir(folder.getPath(), folder.getName());
	}
};

class CreateLocalFolderAction : public FolderAction {
public:
	CreateLocalFolderAction(const Folder& folder) : FolderAction(folder) { }

	bool doIt(Daemon* daemon) {
		try {
			daemon->getDisk()->create(folder);
		}
		catch(FileSystemError& e){
			return false;
		}
		return daemon->askList(folder.getFullPath());
	}
};

class DeleteFolderAction : public FolderAction {
public:
	DeleteFolderAction(const Folder& folder) : FolderAction(folder) { }

	bool doIt(Daemon* daemon) {
		return daemon->askDelete(folder.getPath(), folder.getName());
	}
};

class DeleteLocalFolderAction : public FolderAction {
public:
	DeleteLocalFolderAction(const Folder& folder) : FolderAction(folder) { }

	bool doIt(Daemon* daemon) {
		try {
			daemon->getDisk()->remove(folder);
			return true;
		}
		catch(FileSystemError& e){
			return false;
		}
	}
};


}

#endif // _ACTION_H_
